#include <QtGui>

#include <math.h>

#include "renderarea.h"

RenderArea::RenderArea(QWidget *parent)
    : QWidget(parent)
{
    setBackgroundRole(QPalette::Base);
}

QSize RenderArea::minimumSizeHint() const
{
    return QSize(50, 50);
}

QSize RenderArea::sizeHint() const
{
    return QSize(512, 512);
}

// didziausias bendras daliklis
int dbd(int x, int y)
{
    x = abs(x);
    y = abs(y);
    if (x > y) {
        int tmp = x;
        x = y;
        y = tmp;
    }
    // y visada didesnis
    int dbd = x;
    while (y%dbd!=0 || x%dbd!=0) dbd--;
    return dbd;
}

// sveikos skaiciaus kelimas sveiku laipsiu
int ipow(int x, int y)
{
    if (y <= 0) return 1;
    int power = x;
    while (--y)
        x *= power;
    return x;
}

// atstumas tarp dvieju tasku
double len2p(double x1, double y1, double x2, double y2)
{
    double x = x2-x1;
    double y = y2-y1;
    return sqrt(x*x + y*y);
}

void RenderArea::setStep(int n)
{
    // 2^n-1      gulsciu bruksniu
    // 2^n        skersu  bruksniu (2^(s + 1) tasku)
    // 2^(n+1)-1  viso    bruksniu
    
    // bruksniai aukstyje, galai
    // 1:   1/2            1/3   2/3   ---
    
    // 2:   1/4            1/9   2/9   --
    //      2/4            3/9   6/9   ---
    //      3/4            7/9   8/9   --
    
    // 3:   1/8    1       1/27  2/27  -
    //      2/8    3       3/27  6/27  --
    //      3/8    1       7/27  8/27  -
    //      4/8    9       9/27 18/27  ---
    //      5/8    1      19/27 20/27  -
    //      6/8    3      21/27 24/27  --
    //      7/8    1      25/27 26/27  -
    
    // 4:   1/16   1       1/81  2/81
    //      2/16   3       3/81  6/81  -
    //      3/16   1       7/81  8/81
    //      4/16   9       9/81 18/81  --
    //      5/16   1      19/81 20/81 
    //      6/16   3      21/81 24/81  -
    //      7/16   1      25/81 26/81
    //      8/16  27      27/81 54/81  ---
    //      9/16   1      55/81 56/81
    //     10/16   3      57/81 60/81  -
    //     11/16   1      61/81 62/81
    //     12/16   9      63/81 72/81  --
    //     13/16   1      73/81 74/81
    //     14/16   3      75/81 78/81  -
    //     15/16   1      79/81 80/81
    QApplication::setOverrideCursor(Qt::WaitCursor);

    path = QPainterPath();
    //path.moveTo(0,0);
    int pow2n = ipow(2,n);
    int pow3n = ipow(3,n);
    int x = 1;
    double length = 0.0, old_x2 = 0.0, old_y = 0.0;
    for (int i = 1; i <= pow2n; ++i)
    {
        double y  = (double)i / pow2n;
        double x1 = (double)x / pow3n;
        x += dbd(x, pow3n);
        double x2 = (double)x / pow3n;

        path.lineTo(x1,y);
        if (i != pow2n)
             path.lineTo(x2,y);

        x++;

        length += len2p(old_x2, old_y, x1, y);
        if (i != pow2n)
            length += len2p(x1, y, x2, y);

        old_x2 = x2;
        old_y = y;
    }

    //emit lengthChanged(path.length());
    emit lengthChanged(length);
    update();
    QApplication::restoreOverrideCursor();
}

void RenderArea::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //painter.setRenderHint(QPainter::Antialiasing);
    painter.scale(width(), -height());
    painter.translate(0.0, -1.0);

    painter.setPen(Qt::red);

    painter.drawPath(path);
}
